package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.dao.PaasProcessDataDao;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.IndependentFundRollbackDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.CustomerStatementEntity;
import com.xbongbong.saas.domain.entity.CustomerStatementSnapshotEntity;
import com.xbongbong.saas.domain.entity.FundSetEntity;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.enums.CustomerStatementEnum;
import com.xbongbong.saas.enums.CustomerStatementSnapshotEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.model.CustomerStatementModel;
import com.xbongbong.saas.model.CustomerStatementSnapshotModel;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.script.tempenum.TempPaymentEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: 汪腾伟
 * @date: 2021/3/22
 * @desrcption: 用于独立版资金相关功能数据回滚
 * @version:1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/fundRollback")
public class IndependentFundRollbackScriptController {

    private static final Logger LOG = LoggerFactory.getLogger(IndependentFundRollbackScriptController.class);

    @Resource
    private PaymentModel paymentModel;
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FundSetModel fundSetModel;
    @Resource
    private PaasProcessDataDao paasProcessDataDao;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private CustomerStatementModel customerStatementModel;
    @Resource
    private CustomerStatementSnapshotModel customerStatementSnapshotModel;
    @Resource
    private EsHelper esHelper;

    /**
     * 清除应收款中来源单据是回款计划的,num_64存具体业务的值
     *
     * @param independentFundRollbackDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clearPaymentTaskSource", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clearPaymentTaskSource(@RequestBody @Valid IndependentFundRollbackDTO independentFundRollbackDTO, BindingResult br) {
        try {
            if (!proBaseConfig.getXbbCode().equals(independentFundRollbackDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.info("-----------清除应收款来源单据是回款计划的数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> paymentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paymentMap.put("del", 0);
            //每次查询500条
            Integer pageNum = 100;
            Long idGte = 0L;
            Long maxId = paymentModel.getMaxId(paymentMap);
            Integer start = 0;
            paymentMap.put("start", start);
            paymentMap.put("pageNum", pageNum);
            paymentMap.put("orderByStr", "id asc");
            while (true) {
                paymentMap.put("idGte", idGte);
                //获取要处理的数据
                List<PaymentEntityExt> paymentEntityExts = paymentModel.findEntitys(paymentMap);
                LOG.warn("处理进度：已处理到 tb_saas_payment.id " + idGte + " / " + maxId);
                if (CollectionUtils.isEmpty(paymentEntityExts)) {
                    break;
                }
                idGte = paymentEntityExts.get(paymentEntityExts.size() - 1).getId();
                List<PaymentEntityExt> updateList = new ArrayList<>();
                for (PaymentEntityExt paymentEntityExt : paymentEntityExts) {
                    JSONObject data = paymentEntityExt.getData();
                    int sourceRefType = data.getIntValue(PaymentEnum.SOURCE_REF_TYPE.getAttr());
                    if (sourceRefType == XbbRefTypeEnum.PAYMENT_TASK.getCode()) {
                        data.put(PaymentEnum.SOURCE_REF_TYPE.getAttr(), null);
                        data.put(PaymentEnum.SOURCE.getAttr(), null);
                        data.put(PaymentEnum.SOURCE_LINK_TEXT.getAttr(), null);
                        updateList.add(paymentEntityExt);
                    }
                }
                //下面就是更新应收款数据库和更新es的操作
                if (updateList.size() > 0) {
                    paymentModel.updateBatchAll(updateList);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/fundRollback/clearPaymentTaskSource over");
        } catch (Exception e) {
            LOG.error("清除应收款中来源单据是回款计划的数据:" + e, e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 处理独立版资金相关业务的表单解释
     *
     * @param independentFundRollbackDTO
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/explains/rollBackFundThree", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String rollBackFundThree(@RequestBody @Valid IndependentFundRollbackDTO independentFundRollbackDTO, BindingResult br) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(independentFundRollbackDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.warn("-----------rollBackFundThree start 开始执行独立版应收规则改造 /应收款模板解释-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            Integer businessTypePayment = XbbRefTypeEnum.PAYMENT.getCode();
            Integer businessTypeSheet = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
            Integer businessTypeContract = XbbRefTypeEnum.CONTRACT.getCode();
            List<Integer> businessTypeList = Arrays.asList(businessTypePayment, businessTypeSheet, businessTypeContract);
            //移除默认解释缓存
            removeDefaultExplainRedis(businessTypeList);
            param.put("businessTypeIn", businessTypeList);
            Long maxId = paasFormExplainModel.getMaxId(param);
            Integer start = 0;
            //每次查询300条
            Integer pageNum = 300;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            /*
             1、应收款
             （1）增加：添加应收款
             （2）更改：预计回款日期描述：手动创建应收模式下...。应收生成日期描述：手动创建应收模式下...。
             2、回款单
             （1）关联应收款，并更改其是否可以编辑必填（原来置灰不让设置必填）
             （2）关联合同隐藏字段的fieldType更改
             3、合同
             （1）修改：合同订单中的回款计划名称改为应收款，对应businessType从新回款计划更改为应收款
             */
            //==========================下面是对应收款模板的处理
            //----------新增
            Class<PaymentEnum> paymentEnumClass = PaymentEnum.class;
            PaymentEnum paymentAddPaymentEnum = PaymentEnum.ADD_PAYMENT;
            List<String> paymentEnumAttrs = InitExplainsHelper.getBusinessEnumAttrs(paymentEnumClass);
            FieldAttrEntity newFieldAttrEntityAddPayment = InitExplainsHelper.setField(paymentEnumClass, paymentEnumAttrs, paymentAddPaymentEnum);
            TempPaymentEnum.initAddPayment(newFieldAttrEntityAddPayment);
            String payEstimateTime = PaymentEnum.ESTIMATE_TIME.getAttr();
            String payGenerationDate = PaymentEnum.GENERATION_DATE.getAttr();
            //==========================下面是对回款单模板的处理
            String attrPayment = PaymentSheetEnum.PAYMENT.getAttr();
            PaymentSheetEnum enumContractLink = PaymentSheetEnum.CONTRACT_LINK_TEXT;
            //==========================下面是对合同模板的处理
            //-----------修改回款计划改为应收款，且类型也从回款计划改为应收款；且如果应收规则非计划模式，则需要把该应收款字段隐藏
            ContractEnum enumContractAddPayment = ContractEnum.ADD_PAYMENT;
            Map<String, Object> fundSetParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fundSetParam.put("del", 0);
            fundSetParam.put("columns", "corpid");
            //非计划模式
            fundSetParam.put("negSysLong10", ModelTypeEnum.PLAN.getCode());
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_paas_form_explain.id " + idGte + " / " + maxId);
                //表单解释列表
                List<PaasFormExplainEntity> explainList = paasFormExplainModel.list(param);
                if (explainList == null || explainList.size() == 0) {
                    break;
                }
                idGte = explainList.get(explainList.size() - 1).getId();
                Set<String> corpidIn = explainList.stream().map(e -> e.getCorpid()).collect(Collectors.toSet());
                fundSetParam.put("corpidIn", corpidIn);
                //得到非计划模式的
                List<FundSetEntity> notPlanSetList = fundSetModel.findEntitys(fundSetParam);
                List<String> notPlanCorpidIn = notPlanSetList.stream().map(s -> s.getCorpid()).collect(Collectors.toList());
                List<PaasFormExplainEntity> updateList = new ArrayList<>();
                for (PaasFormExplainEntity explainEntity : explainList) {
                    if (StringUtil.isEmpty(explainEntity.getExplains()) || Objects.equals("[]", explainEntity.getExplains())) {
                        //如果该公司使用的默认解释（未修改过模板），则不处理。需要同步处理缓存（防止线上有生效时间为一天的原explain缓存）
                        continue;
                    }
                    List<FieldAttrEntity> fieldAttrList = JsonHelperUtil.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
                    boolean addFlag = true;
                    if (Objects.equals(explainEntity.getBusinessType(), businessTypePayment)) {
                        //下面是对应收款的处理
                        for (int i = 0; i < fieldAttrList.size(); i++) {
                            FieldAttrEntity fieldAttrEntity = fieldAttrList.get(i);
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(newFieldAttrEntityAddPayment.getAttr(), attr)) {
                                addFlag = false;
                                fieldAttrList.set(i, newFieldAttrEntityAddPayment);
                            }else if (Objects.equals(attr, payEstimateTime)) {
                                fieldAttrEntity.setEditable(BasicConstant.ONE);
                                fieldAttrEntity.setEditForbidden(BasicConstant.ONE);
                                fieldAttrEntity.setShowEditable(BasicConstant.ONE);
                                fieldAttrEntity.setUnableEditMemo(null);
                                fieldAttrEntity.setMemo(I18nMessageUtil.getMessage(I18nStringConstant.ESTIMATE_TIME_MEMO));
                            }else if (Objects.equals(attr, PaymentEnum.SOURCE.getAttr())) {
                                fieldAttrEntity.setRequired(BasicConstant.ZERO);
                            }else if (Objects.equals(attr, PaymentEnum.PAYMENT_TYPE.getAttr())) {
                                fieldAttrEntity.setIsOpen(1);
                            }else if (Objects.equals(payGenerationDate, attr)) {
                                fieldAttrEntity.setMemo(I18nMessageUtil.getMessage(I18nStringConstant.GENERATION_TIME_MEMO));
                            }
                        }
                        if (addFlag) {
                            fieldAttrList.add(newFieldAttrEntityAddPayment);
                        }
                    } else if (Objects.equals(explainEntity.getBusinessType(), businessTypeSheet)) {
                        Iterator<FieldAttrEntity> iterator = fieldAttrList.iterator();
                        while (iterator.hasNext()) {
                            FieldAttrEntity fieldAttrEntity = iterator.next();
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(attrPayment, attr)) {
                                fieldAttrEntity.setSetType(PaymentSheetEnum.PAYMENT.getSetType());
                            } else if (Objects.equals(enumContractLink.getAttr(), attr)) {
                                fieldAttrEntity.setFieldType(enumContractLink.getFieldType());
                            }else if (Objects.equals(PaymentSheetEnum.PAYMENT_TASK.getAttr(), attr)) {
                                iterator.remove();
                            }
                        }
                    } else if (Objects.equals(explainEntity.getBusinessType(), businessTypeContract)) {
                        for (FieldAttrEntity fieldAttrEntity : fieldAttrList) {
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(enumContractAddPayment.getAttr(), attr)) {
                                fieldAttrEntity.setAttrName(enumContractAddPayment.getAttrName());
                                fieldAttrEntity.setDefaultName(enumContractAddPayment.getAttrName());
                                SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                                saasParticularAttributePoJo.setLinkBusinessType(XbbRefTypeEnum.PAYMENT.getCode());
                                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                                if (notPlanCorpidIn.contains(explainEntity.getCorpid())) {
                                    //非手动创建应收模式，合同模板内该应收款
                                    fieldAttrEntity.setIsOpen(BasicConstant.ZERO);
                                    fieldAttrEntity.setIsForbidden(BasicConstant.ZERO);
                                }
                                fieldAttrEntity.setSaasAttr(ContractEnum.ADD_PAYMENT.getSaasAttr());
                            }
                        }
                    }
                    String explains = JSON.toJSONString(fieldAttrList);
                    explainEntity.setExplains(explains);
                    updateList.add(explainEntity);
                }
                if (CollectionsUtil.isNotEmpty(updateList)) {
                    paasFormExplainModel.updateBatchExplains(updateList);
                }
            }
            LOG.warn("-----------time consume explainsFundThree:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------/script/fundRollback/explains/rollBackFundThree over");
        } catch (Exception e) {
            LOG.error("/script/fundRollback/explains/rollBackFundThree error", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 强制把有改动的表单模板默认解释从缓存移除
     * @param businessTypeList
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void removeDefaultExplainRedis(List<Integer> businessTypeList) {
        String corpid = "0";
        for (Integer businessType : businessTypeList) {
            String redisKey = corpid + "_" + businessType;
            paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, redisKey);
        }
    }

    /**
     * 迁移合同中带有回款计划的数据，如果这个回款计划是新建的就不管了，但是如果是编辑进审批的就需要根据合同去查询出对应的应收款数据.总结一下有以下几种情况
     * （1）合同新建回款计划，脚本执行完之后审批中合同就不带有回款计划
     * （2）合同新增两条回款计划进审批，审批通过，这时候编辑合同进审批。这时候回款计划得用应收款替代。
     * （3）基于第二种情形，合同带有两个回款计划然后编辑合同添加一条新的回款计划，这时候进审批是合同带有三条回款计划，脚本执行完之后只会有两条回款计划。
     *
     * @param independentFundRollbackDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/migrateOldProcessData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String migrateOldProcessData(@RequestBody @Valid IndependentFundRollbackDTO independentFundRollbackDTO, BindingResult br) throws XbbException {
        try {
            if (!proBaseConfig.getXbbCode().equals(independentFundRollbackDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.info("-----------迁移合同中带有新回款计划的数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> processDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            processDataMap.put("del", 0);
            processDataMap.put("businessType", XbbRefTypeEnum.CONTRACT.getCode());
            //每次查询500条
            Integer pageNum = 500;
            Long idGte = 0L;
            Long maxId = paasProcessDataDao.getMaxId(processDataMap);
            Integer start = 0;
            processDataMap.put("start", start);
            processDataMap.put("pageNum", pageNum);
            processDataMap.put("orderByStr", "id asc");
            while (true) {
                processDataMap.put("idGte", idGte);
                //获取要处理的数据
                List<PaasProcessDataEntity> processDataEntities = paasProcessDataDao.findEntitys(processDataMap);
                LOG.warn("处理进度：已处理到 tb_paas_process_data.id " + idGte + " / " + maxId);
                if (CollectionUtils.isEmpty(processDataEntities)) {
                    break;
                }
                idGte = processDataEntities.get(processDataEntities.size() - 1).getId();
                List<PaasProcessDataEntity> updateList = new ArrayList<>();
                Set<String> contractIdSet = new HashSet<>();
                for (PaasProcessDataEntity paasProcessDataEntity : processDataEntities) {
                    Long formDataId = paasProcessDataEntity.getFormDataId();
                    String data = paasProcessDataEntity.getData();
                    JSONObject jsonObject = JSON.parseObject(data);
                    JSONArray jsonArray = jsonObject.getJSONArray("array_1");
                    if (Objects.isNull(jsonArray) || jsonArray.size() == BasicConstant.ZERO) {
                        continue;
                    }
                    Iterator<Object> jsonObjectIterator = jsonArray.iterator();
                    while (jsonObjectIterator.hasNext()) {
                        JSONObject jsonObjectSen = (JSONObject)(jsonObjectIterator.next());
                        Long id = jsonObjectSen.getLong(BasicConstant.ID);
                        if (Objects.isNull(id)) {
                            //代表是新建进审批的，需要把这条应收款给移除掉
                            jsonObjectIterator.remove();
                        }
                    }
                    if (formDataId > 0) {
                        contractIdSet.add(String.valueOf(formDataId));
                    }
                    //JSON转回去
                    String fininalJson = JSON.toJSONString(jsonObject);
                    paasProcessDataEntity.setData(fininalJson);
                }
                //根据合同id查询出与这些合同关联出的应收款
                Map<String, Object> paymentMap = new HashMap<>();
                paymentMap.put("del", 0);
                paymentMap.put("contractIdIn",contractIdSet);
                List<PaymentEntityExt> paymentEntityExts = paymentModel.findEntitys(paymentMap);
                for (PaasProcessDataEntity paasProcessDataEntity : processDataEntities) {
                    Long formDataId = paasProcessDataEntity.getFormDataId();
                    JSONArray array1JsonArray = new JSONArray();
                    for (PaasFormDataEntityExt paasFormDataEntityExt : paymentEntityExts) {
                        JSONObject data = paasFormDataEntityExt.getData();
                        String contractId = data.getString(PaymentEnum.CONTRACT.getAttr());
                        if (Objects.equals(String.valueOf(formDataId), contractId)) {
                            JSONObject newPaymentJson = new JSONObject();
                            newPaymentJson.put(BasicConstant.ID, paasFormDataEntityExt.getId());
                            newPaymentJson.put("del", 0);
                            newPaymentJson.put(BasicConstant.DATA, data);
                            newPaymentJson.put("serialNo", paasFormDataEntityExt.getSerialNo());
                            array1JsonArray.add(newPaymentJson);
                        }
                    }
                    //JSON转回去
                    if (Objects.nonNull(array1JsonArray) && array1JsonArray.size() > 0) {
                        String data = paasProcessDataEntity.getData();
                        JSONObject jsonObject = JSON.parseObject(data);
                        jsonObject.put(ContractEnum.ADD_PAYMENT.getAttr(), array1JsonArray);
                        String fininalJson = JSON.toJSONString(jsonObject);
                        paasProcessDataEntity.setData(fininalJson);
                    }
                    updateList.add(paasProcessDataEntity);
                }
                if (CollectionsUtil.isNotEmpty(updateList)) {
                    paasProcessDataDao.updateBatchProcessData(updateList);
                    //清理大对象
                    processDataEntities.clear();
                    updateList.clear();
                }

            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/fundRollback/migrateOldProcessData over");
        }catch (XbbException e) {
            LOG.error("迁移合同中带有回款计划的数据:" + e, e);
            //return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 清除对账单中来源单据是回款计划的,num_3存具体业务的值
     *
     * @param independentFundRollbackDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clearStatementSource", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clearStatementSource(@RequestBody @Valid IndependentFundRollbackDTO independentFundRollbackDTO, BindingResult br) {
        try {
            if (!proBaseConfig.getXbbCode().equals(independentFundRollbackDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.info("-----------清除对账单来源单据是回款计划的数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            //每次查询500条
            Integer pageNum = 100;
            Long idGte = 0L;
            Long maxId = customerStatementModel.getMaxId(param);
            Integer start = 0;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            while (true) {
                param.put("idGte", idGte);
                //获取要处理的数据
                List<CustomerStatementEntity> list = customerStatementModel.findEntitys(param);
                LOG.warn("处理进度：已处理到 tb_saas_customer_statement.id " + idGte + " / " + maxId);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                idGte = list.get(list.size() - 1).getId();
                List<CustomerStatementEntity> updateList = new ArrayList<>();
                for (CustomerStatementEntity entity : list) {
                    JSONObject data = entity.getData();
                    int sourceRefType = data.getIntValue(CustomerStatementEnum.SOURCE_TYPE.getAttr());
                    if (sourceRefType == XbbRefTypeEnum.PAYMENT_TASK.getCode()) {
                        data.put(CustomerStatementEnum.SOURCE_TYPE.getAttr(), null);
                        data.put(CustomerStatementEnum.SOURCE_ID.getAttr(), null);
                        data.put(CustomerStatementEnum.SOURCE_NO.getAttr(), null);
                        updateList.add(entity);
                    }
                }
                if (updateList.size() > 0) {
                    customerStatementModel.updateBatchAbnormal(updateList, null);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/fundRollback/clearStatementSource over");
        } catch (Exception e) {
            LOG.error("清除对账单中来源单据是回款计划的数据 error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 清除对账单中来源单据是回款计划的,num_3存具体业务的值
     * SELECT count(*) FROM tb_saas_customer_statement_snapshot 2021年3月30日让小胡查的有65条数据
     *
     * @param independentFundRollbackDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clearStatementSnapshotSource", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clearStatementSnapshotSource(@RequestBody @Valid IndependentFundRollbackDTO independentFundRollbackDTO, BindingResult br) {
        try {
            if (!proBaseConfig.getXbbCode().equals(independentFundRollbackDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LOG.info("-----------清除对账单快照来源单据是回款计划的数据-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            //每次查询500条
            Integer pageNum = 100;
            Long idGte = 0L;
            Integer start = 0;
            param.put("start", start);
            param.put("pageSize", pageNum);
            param.put("orderByStr", "id asc");
            while (true) {
                param.put("idGte", idGte);
                //获取要处理的数据
                List<CustomerStatementSnapshotEntity> list = customerStatementSnapshotModel.findEntitys(param);
                LOG.warn("处理进度：已处理到 tb_saas_customer_statement.id " + idGte);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                idGte = list.get(list.size() - 1).getId();
                List<CustomerStatementSnapshotEntity> updateList = new ArrayList<>();
                for (CustomerStatementSnapshotEntity entity : list) {
                    JSONObject data = entity.getData();
                    int sourceRefType = data.getIntValue(CustomerStatementSnapshotEnum.SOURCE_TYPE.getAttr());
                    if (sourceRefType == XbbRefTypeEnum.PAYMENT_TASK.getCode()) {
                        data.put(CustomerStatementSnapshotEnum.SOURCE_TYPE.getAttr(), null);
                        data.put(CustomerStatementSnapshotEnum.SOURCE_ID.getAttr(), null);
                        data.put(CustomerStatementSnapshotEnum.SOURCE_NO.getAttr(), null);
                        updateList.add(entity);
                    }
                }
                if (updateList.size() > 0) {
                    customerStatementSnapshotModel.updateBatchAbnormal(updateList, null);
                }
            }
            LOG.info("-----------time end:" + (DateTimeUtil.getInt() - timeStart));
            LOG.info("-----------/script/fundRollback/clearStatementSnapshotSource over");
        } catch (Exception e) {
            LOG.error("清除对账单快照来源单据是回款计划的数据 error", e);
            return JSON.toJSONString("{\"msg\":\"fail\"}");
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }
}
